package com.farmUni.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.farmUni.common.BaseContext;
import com.farmUni.entity.*;
import com.farmUni.entity.Vo.ArticleAddVO;
import com.farmUni.entity.Vo.ArticleDetailVO;
import com.farmUni.entity.Vo.ArticleShowVO;
import com.farmUni.mapper.ArticleMapper;
import com.farmUni.service.ArticleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.farmUni.service.LikingService;
import com.farmUni.service.PictureService;
import com.farmUni.service.UserService;
import com.farmUni.utils.Recommend;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Random;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author wxy
 * @since 2024-02-04
 */
@Service
@Transactional
@Slf4j
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

    @Autowired
    private PictureService pictureService;

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private LikingService likingService;
    
    @Autowired
    private UserService userService;

    @Value("${cityView.uploadPath}")
    private String baseUrl;

    @Override
    public List<Long> getArticleIdsOrderByLiking(int offset, int limit) {
        return articleMapper.selectArticleIdsOrderByLiking(offset, limit);
    }

    @Override
    public List<ArticleShowVO> getRecArticle() {
        List<User> users = userService.list();
        List<Long>userIds = new ArrayList<>();
        for(User user : users){
            userIds.add(user.getUserId());
        }
        log.info(userIds.toString());
        LambdaQueryWrapper<Article> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        int limit = 15;
        Random random = new Random();
        List<LuckyUser> luckyUsers = new ArrayList<>();
        Integer integer = articleMapper.selectCount(null);
        log.info("总条数:"+integer);
        for (Long userId : userIds){
            int randomNumber = random.nextInt(integer + 1); // 生成0到10之间的随机数（包括0和10）
            int offset = randomNumber % integer;
            log.info("偏移量" + offset);
//            List<Long> articleIdsOrderByLiking = articleService.getArticleIdsOrderByLiking(offset, 10);
            List<Article> list = this.list(lambdaQueryWrapper
                    .select(Article::getId) // 仅选择 id 列
                    .orderByDesc(Article::getLiking) // 按照点赞数降序排序
                    .last("LIMIT " + offset + ", " + limit)
            );
            LuckyUser luckyUser = new LuckyUser(userId);
            for(Article article : list){
                Liking isLike = likingService.getOne(Wrappers.<Liking>lambdaQuery()
                        .eq(Liking::getArticleId, article.getId())
                        .eq(Liking::getUserId, userId)
                        .last("LIMIT 1"));
                luckyUser.set(article.getId(),isLike != null?10:1);
            }
            luckyUsers.add(luckyUser);
        }
        Recommend recommend = new Recommend();
        List<LuckyArticle> recommendationArticle = recommend.recommend(BaseContext.getCurrentId(), luckyUsers);
        List<Article> articles = new ArrayList<>();
        for (LuckyArticle article : recommendationArticle) {
            articles.add(this.getById(article.articleId));
        }
        List<ArticleShowVO> articleShowVOList = new ArrayList<>();
        int end = 0;
        for (Article article : articles) {
            ArticleShowVO articleShowVO = new ArticleShowVO();
            BeanUtils.copyProperties(article, articleShowVO);
            Picture picture = pictureService.getOne(
                    Wrappers.<Picture>lambdaQuery()
                            .eq(Picture::getArticleId, articleShowVO.getId())
                            .orderByAsc(Picture::getCreateTime)
                            .last("LIMIT 1")
            );
            if (picture != null) {
                articleShowVO.setUrl(baseUrl + picture.getUrl());
            } else {
                articleShowVO.setUrl("");
            }
            articleShowVOList.add(articleShowVO);
            if(end == 5)
                break;
            end ++;
        }

        return articleShowVOList;
    }

    @Override
    public Page<ArticleShowVO> getShowListPlus(int current, int size, String matching){
        Page<Article> pageInfo = new Page<>(current, size);

        if(matching.equals("不限")){
            this.page(pageInfo, Wrappers.<Article>lambdaQuery()
                    .orderByDesc(Article::getCreateTime));
        }else {
            this.page(pageInfo, Wrappers.<Article>lambdaQuery()
                    .eq(Article::getType,matching)
                    .orderByDesc(Article::getCreateTime));
        }
        Page<ArticleShowVO> pageNewInfo = new Page<>(current, size);
        List<ArticleShowVO> articleShowVOList = new ArrayList<>();

        for (Article article : pageInfo.getRecords()) {
            ArticleShowVO articleShowVO = new ArticleShowVO(); // 创建 ArticleShowVO 对象
            BeanUtils.copyProperties(article, articleShowVO); // 复制属性
            // 设置图片 URL
            Picture picture = pictureService.getOne(
                    Wrappers.<Picture>lambdaQuery()
                            .eq(Picture::getArticleId, articleShowVO.getId())
                            .orderByDesc(Picture::getCreateTime)
                            .last("LIMIT 1")
            );
            if (picture != null) {
                articleShowVO.setUrl(baseUrl + picture.getUrl());
            } else {
                articleShowVO.setUrl("");
            }
//            String openId = BaseContext.getCurrentOpenId();
            Long currentId = BaseContext.getCurrentId();

            if (currentId == null || currentId == 0)
                articleShowVO.setIsLike(false);
            else {
                Liking isLike = likingService.getOne(Wrappers.<Liking>lambdaQuery()
                        .eq(Liking::getArticleId, articleShowVO.getId())
                        .eq(Liking::getUserId, currentId)
                        .last("LIMIT 1"));
                articleShowVO.setIsLike(isLike != null);
            }
            articleShowVOList.add(articleShowVO);
        }

        pageNewInfo.setRecords(articleShowVOList); // 设置新的 records 列表
        BeanUtils.copyProperties(pageInfo, pageNewInfo, "records"); // 复制其他属性，但不包括 records
        return pageNewInfo;
    }

    @Override
    public Page<ArticleShowVO> getShowList(int current, int size) {
        Page<Article> pageInfo = new Page<>(current, size);

        this.page(pageInfo, Wrappers.<Article>lambdaQuery()
                .orderByDesc(Article::getCreateTime));

        Page<ArticleShowVO> pageNewInfo = new Page<>(current, size);
        List<ArticleShowVO> articleShowVOList = new ArrayList<>();

        for (Article article : pageInfo.getRecords()) {
            ArticleShowVO articleShowVO = new ArticleShowVO(); // 创建 ArticleShowVO 对象
            BeanUtils.copyProperties(article, articleShowVO); // 复制属性
            // 设置图片 URL
            Picture picture = pictureService.getOne(
                    Wrappers.<Picture>lambdaQuery()
                            .eq(Picture::getArticleId, articleShowVO.getId())
                            .orderByDesc(Picture::getCreateTime)
                            .last("LIMIT 1")
            );
            if (picture != null) {
                articleShowVO.setUrl(baseUrl + picture.getUrl());
            } else {
                articleShowVO.setUrl("");
            }
//            String openId = BaseContext.getCurrentOpenId();
            Long currentId = BaseContext.getCurrentId();
            if (currentId == null || currentId == 0)
                articleShowVO.setIsLike(false);
            else {
                Liking isLike = likingService.getOne(Wrappers.<Liking>lambdaQuery()
                        .eq(Liking::getArticleId, articleShowVO.getId())
                        .eq(Liking::getUserId, currentId)
                        .last("LIMIT 1"));
                articleShowVO.setIsLike(isLike != null);
            }
            articleShowVOList.add(articleShowVO);
        }

        pageNewInfo.setRecords(articleShowVOList); // 设置新的 records 列表
        BeanUtils.copyProperties(pageInfo, pageNewInfo, "records"); // 复制其他属性，但不包括 records
        return pageNewInfo;
    }

    @Override
    public Page<ArticleShowVO> getMyPage(int current, int size) {
//        String openId = BaseContext.getCurrentOpenId();
        Long currentId = BaseContext.getCurrentId();
        Page<Article> pageInfo = new Page<>(current, size);

        this.page(pageInfo, Wrappers.<Article>lambdaQuery()
                .orderByDesc(Article::getCreateTime)
                .eq(Article::getUserId, currentId)); // 假设 this 是一个 MyBatis-Plus 的 Service 实现类

        Page<ArticleShowVO> pageNewInfo = new Page<>(current, size);
        List<ArticleShowVO> articleShowVOList = new ArrayList<>();

        for (Article article : pageInfo.getRecords()) {
            ArticleShowVO articleShowVO = new ArticleShowVO(); // 创建 ArticleShowVO 对象
            BeanUtils.copyProperties(article, articleShowVO); // 复制属性
            // 设置图片 URL
            Picture picture = pictureService.getOne(
                    Wrappers.<Picture>lambdaQuery()
                            .eq(Picture::getArticleId, articleShowVO.getId())
                            .orderByAsc(Picture::getCreateTime)
                            .last("LIMIT 1")
            );
            if (picture != null) {
                articleShowVO.setUrl(baseUrl + picture.getUrl());
            } else {
                articleShowVO.setUrl("");
            }
            Liking isLike = likingService.getOne(Wrappers.<Liking>lambdaQuery()
                    .eq(Liking::getArticleId, articleShowVO.getId())
                    .eq(Liking::getUserId, currentId)
                    .last("LIMIT 1"));
            articleShowVO.setIsLike(isLike != null);
            articleShowVOList.add(articleShowVO);
        }

        pageNewInfo.setRecords(articleShowVOList); // 设置新的 records 列表
        BeanUtils.copyProperties(pageInfo, pageNewInfo, "records"); // 复制其他属性，但不包括 records
        return pageNewInfo;
    }


    @Override
    public Boolean add(ArticleAddVO articleAddVO) {
        articleAddVO.setUserId2(BaseContext.getCurrentId());
        boolean isSuccess = this.save(articleAddVO);
        Long articleId = articleAddVO.getId();
        for (String url : articleAddVO.getUrl()) {
            Picture picture = new Picture();
            picture.setUrl(url);
            picture.setArticleId(articleId);
            pictureService.save(picture);
        }
        return isSuccess;
    }

    @Override
    public ArticleDetailVO getDetail(Long id) {
        Article article = this.getById(id);
        ArticleDetailVO articleDetailVO = new ArticleDetailVO();
        BeanUtils.copyProperties(article, articleDetailVO);
        List<Picture> pictures = pictureService.list(Wrappers.<Picture>lambdaQuery()
                .eq(Picture::getArticleId, id));
        List<String> urls = new ArrayList<>();
        for (Picture picture : pictures) {
            urls.add(baseUrl + picture.getUrl());
        }
//        String openId = BaseContext.getCurrentOpenId();
        Long currentId = BaseContext.getCurrentId();
        if (currentId == 0)
            articleDetailVO.setIsLike(false);
        else {
            Liking isLike = likingService.getOne(Wrappers.<Liking>lambdaQuery()
                    .eq(Liking::getArticleId, articleDetailVO.getId())
                    .eq(Liking::getUserId, currentId)
                    .last("LIMIT 1"));
            articleDetailVO.setIsLike(isLike != null);
        }
        articleDetailVO.setUrls(urls);
        return articleDetailVO;
    }

    @Override
    public List<ArticleShowVO> getCultureOrImpressRec(String type) {
        List<Article> articles = this.list(Wrappers.<Article>lambdaQuery()
                .eq(Article::getType, type)
                .orderByDesc(Article::getLiking)
                .last("LIMIT 3"));
        List<ArticleShowVO> articleShowVOList = new ArrayList<>();
        for (Article article : articles) {
            ArticleShowVO articleShowVO = new ArticleShowVO();
            BeanUtils.copyProperties(article, articleShowVO);
            Picture picture = pictureService.getOne(
                    Wrappers.<Picture>lambdaQuery()
                            .eq(Picture::getArticleId, articleShowVO.getId())
                            .orderByAsc(Picture::getCreateTime)
                            .last("LIMIT 1")
            );
            if (picture != null) {
                articleShowVO.setUrl(baseUrl + picture.getUrl());
            } else {
                articleShowVO.setUrl("");
            }
            articleShowVOList.add(articleShowVO);
        }
        return articleShowVOList;
    }

    @Override
    public List<ArticleShowVO> search(String keyword) {
        keyword.replaceAll("%", "/%").replaceAll("_", "%_");
        List<Article> list = this.list(Wrappers.<Article>lambdaQuery()
                .like(Article::getContent, keyword)
                .or()
                .like(Article::getTitle, keyword)
                .orderByDesc(Article::getCreateTime));
        List<ArticleShowVO> articleShowVOList = new ArrayList<>();
        for (Article article : list) {
            ArticleShowVO articleShowVO = new ArticleShowVO(); // 创建 ArticleShowVO 对象
            BeanUtils.copyProperties(article, articleShowVO); // 复制属性
            // 设置图片 URL
            Picture picture = pictureService.getOne(
                    Wrappers.<Picture>lambdaQuery()
                            .eq(Picture::getArticleId, articleShowVO.getId())
                            .orderByAsc(Picture::getCreateTime)
                            .last("LIMIT 1")
            );
            if (picture != null) {
                articleShowVO.setUrl(baseUrl + picture.getUrl());
            } else {
                articleShowVO.setUrl("");
            }
            Liking isLike = likingService.getOne(Wrappers.<Liking>lambdaQuery()
                    .eq(Liking::getArticleId, articleShowVO.getId())
                    .last("LIMIT 1"));
            articleShowVO.setIsLike(isLike != null);
            articleShowVOList.add(articleShowVO);
        }
        return articleShowVOList;
    }

    @Override
    public List<ArticleShowVO> getTopArticle() {
        List<Article> articles = this.list(Wrappers.<Article>lambdaQuery()
                .orderByDesc(Article::getLiking)
                .last("LIMIT 4"));
        List<ArticleShowVO> articleShowVOList = new ArrayList<>();
        for (Article article : articles) {
            ArticleShowVO articleShowVO = new ArticleShowVO();
            BeanUtils.copyProperties(article, articleShowVO);
            Picture picture = pictureService.getOne(
                    Wrappers.<Picture>lambdaQuery()
                            .eq(Picture::getArticleId, articleShowVO.getId())
                            .orderByAsc(Picture::getCreateTime)
                            .last("LIMIT 1")
            );
            if (picture != null) {
                articleShowVO.setUrl(baseUrl + picture.getUrl());
            } else {
                articleShowVO.setUrl("");
            }
            articleShowVOList.add(articleShowVO);
        }
        return articleShowVOList;
    }

    @Override
    public List<ArticleShowVO> getMarket() {
        List<Article> articles = this.list(Wrappers.<Article>lambdaQuery()
                .eq(Article::getType,"市场动态")
                .orderByDesc(Article::getCreateTime)
                .last("LIMIT 6"));
        List<ArticleShowVO> articleShowVOList = new ArrayList<>();
        for (Article article : articles) {
            ArticleShowVO articleShowVO = new ArticleShowVO();
            BeanUtils.copyProperties(article, articleShowVO);
            Picture picture = pictureService.getOne(
                    Wrappers.<Picture>lambdaQuery()
                            .eq(Picture::getArticleId, articleShowVO.getId())
                            .orderByAsc(Picture::getCreateTime)
                            .last("LIMIT 1")
            );
            if (picture != null) {
                articleShowVO.setUrl(baseUrl + picture.getUrl());
            } else {
                articleShowVO.setUrl("");
            }
            articleShowVOList.add(articleShowVO);
        }
        return articleShowVOList;
    }

    @Override
    public List<ArticleShowVO> getFrontier() {
        List<Article> articles = this.list(Wrappers.<Article>lambdaQuery()
                .eq(Article::getType,"科技前沿")
                .orderByDesc(Article::getCreateTime)
                .last("LIMIT 6"));
        List<ArticleShowVO> articleShowVOList = new ArrayList<>();
        for (Article article : articles) {
            ArticleShowVO articleShowVO = new ArticleShowVO();
            BeanUtils.copyProperties(article, articleShowVO);
            Picture picture = pictureService.getOne(
                    Wrappers.<Picture>lambdaQuery()
                            .eq(Picture::getArticleId, articleShowVO.getId())
                            .orderByAsc(Picture::getCreateTime)
                            .last("LIMIT 1")
            );
            if (picture != null) {
                articleShowVO.setUrl(baseUrl + picture.getUrl());
            } else {
                articleShowVO.setUrl("");
            }
            articleShowVOList.add(articleShowVO);
        }
        return articleShowVOList;
    }

    @Override
    public List<ArticleShowVO> getPolicy() {
        List<Article> articles = this.list(Wrappers.<Article>lambdaQuery()
                .eq(Article::getType,"政策法规")
                .orderByDesc(Article::getCreateTime)
                .last("LIMIT 6"));
        List<ArticleShowVO> articleShowVOList = new ArrayList<>();
        for (Article article : articles) {
            ArticleShowVO articleShowVO = new ArticleShowVO();
            BeanUtils.copyProperties(article, articleShowVO);
            Picture picture = pictureService.getOne(
                    Wrappers.<Picture>lambdaQuery()
                            .eq(Picture::getArticleId, articleShowVO.getId())
                            .orderByAsc(Picture::getCreateTime)
                            .last("LIMIT 1")
            );
            if (picture != null) {
                articleShowVO.setUrl(baseUrl + picture.getUrl());
            } else {
                articleShowVO.setUrl("");
            }
            articleShowVOList.add(articleShowVO);
        }
        return articleShowVOList;
    }

    @Override
    public List<ArticleShowVO> getMedication() {
        List<Article> articles = this.list(Wrappers.<Article>lambdaQuery()
                .eq(Article::getType,"科学用药")
                .orderByDesc(Article::getCreateTime)
                .last("LIMIT 6"));
        List<ArticleShowVO> articleShowVOList = new ArrayList<>();
        for (Article article : articles) {
            ArticleShowVO articleShowVO = new ArticleShowVO();
            BeanUtils.copyProperties(article, articleShowVO);
            Picture picture = pictureService.getOne(
                    Wrappers.<Picture>lambdaQuery()
                            .eq(Picture::getArticleId, articleShowVO.getId())
                            .orderByAsc(Picture::getCreateTime)
                            .last("LIMIT 1")
            );
            if (picture != null) {
                articleShowVO.setUrl(baseUrl + picture.getUrl());
            } else {
                articleShowVO.setUrl("");
            }
            articleShowVOList.add(articleShowVO);
        }
        return articleShowVOList;
    }

    @Override
    public List<ArticleShowVO> getEducation(String edu) {
        List<Article> articles = this.list(Wrappers.<Article>lambdaQuery()
                .eq(Article::getType,edu)
                .orderByDesc(Article::getCreateTime));
        List<ArticleShowVO> articleShowVOList = new ArrayList<>();
        for (Article article : articles) {
            ArticleShowVO articleShowVO = new ArticleShowVO();
            BeanUtils.copyProperties(article, articleShowVO);
            Picture picture = pictureService.getOne(
                    Wrappers.<Picture>lambdaQuery()
                            .eq(Picture::getArticleId, articleShowVO.getId())
                            .orderByAsc(Picture::getCreateTime)
                            .last("LIMIT 1")
            );
            if (picture != null) {
                articleShowVO.setUrl(baseUrl + picture.getUrl());
            } else {
                articleShowVO.setUrl("");
            }
            articleShowVOList.add(articleShowVO);
        }
        return articleShowVOList;
    }


}
